package com.hyou.springboot.aop;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;

import com.hyou.springboot.annotation.Auth;
import com.hyou.springboot.consts.SessionPrefix;
import com.hyou.springboot.util.ResponseMessageUtil;

/**
 * 权限判断AOP
 * 
 * @author FengChangshuo
 * @version 1.0.0 2018-11-06 15:06:25 初始创建
 */
@Order(0)
@Aspect
@Component("authAspect")
public class AuthAspect {
    
    private static final Logger log = LoggerFactory.getLogger(AuthAspect.class);
    
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    
    @Pointcut("@annotation(com.hyou.springboot.annotation.Auth)")
    public void authPoint() {
        // 切入点标记
    }
    
    @Around("authPoint()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Auth auth = methodSignature.getMethod().getAnnotation(Auth.class);
        String authValue = auth.value();
        
        if (StringUtils.isBlank(authValue)) {
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            log.warn("method : {}.{}, Auth Annotation value值不能为空！", className, methodName);
            return ResponseMessageUtil.genNoPermissionResult();
        }
        
        String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
        
        Boolean hasAuth = redisTemplate.boundHashOps(SessionPrefix.SESSION + sessionId).hasKey(authValue);
        if (!hasAuth) {
            log.debug("缺少权限： {}", authValue);
            return ResponseMessageUtil.genNoPermissionResult();
        }
        
        return joinPoint.proceed();
    }
    
}
